#include <fstream>
#include <iostream>
#include <vector>

#include "cista/reflection/for_each_field.h"
#include "cista/targets/file.h"
#include "cista/serialization.h"

using namespace cista;

int main(int argc, char **argv)
{
  struct test
  {
    int a_ = 1;
    int b_ = 2;
    int c_ = 3;
  } t;

  struct test1
  {
    uint64_t number_ = 77;
  } t1;

  {
    cista::file f{"a.dat", "w+"};
    cista::serialize(f, t);
    cista::serialize(f, t1);

    std::vector<unsigned char> buf = cista::serialize(t);
    std::vector<unsigned char> vT = cista::serialize(t1);
    int nT = buf.size();
    buf.insert(buf.end(), vT.begin(), vT.end());
    auto r = cista::deserialize<test>(buf);
    auto r1 = cista::deserialize<test1>(vT);
    auto r2 = cista::deserialize<test1>(vT.data(), vT.data() + vT.size());
    unsigned char *p = vT.data();
    auto r3 = cista::deserialize<test1>(p, p + vT.size());
    unsigned char *p2 = buf.data();
    p2 += nT;
    char cT[64];
    memset(cT, 0, sizeof(cT));
    memcpy(cT, p2, vT.size());
    auto r4 = cista::deserialize<test1>(cT, cT + vT.size());
    // 在使用mode::CAST模式时，cista::deserialize<T>(CharT *from, CharT *to)直接对from进行类型转换，不使用to参数，
    // 其它模式需要判断to参数，并且from参数必须8字节对齐，否则报"ptr alignment"异常
    auto r5 = cista::deserialize<test1, mode::CAST>(p2);
    auto r6 = cista::deserialize<test1, mode::CAST>(p2, p2 + vT.size());
    // auto r7 = cista::deserialize<test1>(p2, p2+vT.size());

    printf("r:%d,%d,%d\n", r->a_, r->b_, r->c_);
    printf("r1:%ld\n", r1->number_);
    printf("r2:%ld\n", r2->number_);
    printf("r3:%ld\n", r3->number_);
    printf("r4:%ld\n", r4->number_);
    printf("r5:%ld\n", r5->number_);
    printf("r6:%ld\n", r6->number_);
  }

  {
    struct testA
    {
      test t;
      test1 t1;
    }t2;

    cista::file f{"b.dat", "w+"};
    cista::serialize(f, t2);

    std::vector<unsigned char> buf = cista::serialize(t2);
    auto r = cista::deserialize<testA>(buf);

    printf("r:%d,%d,%d,%ld\n", r->t.a_, r->t.b_, r->t.c_, r->t1.number_);
  }

  {
    struct testT
    {
      int i;
      //int *pi;
      //char *pc;
      cista::raw::vector<int> vi;
      //std::vector<std::vector<int>> vvi;
    }t;
    t.i = 1;
    //t.pi = new int;
    //*t.pi = 2;
    //t.pc = new char[128];
    //for (size_t i = 0; i < 128; i++)
    //{
    //  t.pc[i] = i;
    //}
    t.vi = {100,101,102,103};
    //t.vvi = {{200}, {300,301}, {400,401,402}};

    std::vector<unsigned char> buf = cista::serialize(t);
    auto r = cista::deserialize<testT>(buf);

    printf("r:%d,%d\n", r->i, r->vi[0]);
    //printf("r:%d,%d,%d,%d,%d,%d\n", r->i, *r->pi, r->pc[0x33], r->vi[0], r->vvi[0][0], r->vvi[2][2]);
  }
}
